<template>
  <div class="grid" style="gap: 12px">
    <GlassCard>
      <el-form label-position="left" label-width="auto" class="fx-compact">
        <div class="top-row">
          <el-tag class="code-tag" size="small">
            <span
              class="fi"
              :class="
                'fi-' + (currencyToCountry(state.from) || '').toLowerCase()
              "></span>
            {{ state.from }}
          </el-tag>
          <el-input-number
            v-model="state.amount"
            :min="0"
            :step="1"
            :precision="2"
            :style="{ width: '100%' }"
            controls-position="right" />
          <el-icon class="swap-icon" @click="swap()"><Switch /></el-icon>
        </div>

        <div
          style="
            margin-top: 12px;
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 12px;
            align-items: end;
          ">
          <el-form-item label="从">
            <el-select v-model="state.from" filterable style="width: 100%">
              <template #prefix>
                <span
                  class="fi"
                  :class="
                    'fi-' + (currencyToCountry(state.from) || '').toLowerCase()
                  "></span>
              </template>
              <el-option
                v-for="c in currencies"
                :key="c"
                :label="displayLabel(c)"
                :value="c">
                <span
                  class="fi mr-1"
                  :class="
                    'fi-' + (currencyToCountry(c) || '').toLowerCase()
                  "></span>
                <span>{{ displayLabel(c) }}</span>
              </el-option>
            </el-select>
          </el-form-item>

          <el-form-item label="到">
            <el-select v-model="state.to" filterable style="width: 100%">
              <template #prefix>
                <span
                  class="fi"
                  :class="
                    'fi-' + (currencyToCountry(state.to) || '').toLowerCase()
                  "></span>
              </template>
              <el-option
                v-for="c in currencies"
                :key="c"
                :label="displayLabel(c)"
                :value="c">
                <span
                  class="fi mr-1"
                  :class="
                    'fi-' + (currencyToCountry(c) || '').toLowerCase()
                  "></span>
                <span>{{ displayLabel(c) }}</span>
              </el-option>
            </el-select>
          </el-form-item>
        </div>

        <div class="fx-result">
          <span class="num">{{ convertedText }}</span>
          <span class="code">{{ state.to }}</span>
          <el-button
            circle
            text
            size="small"
            @click="copyToClipboard(convertedText + ' ' + state.to)">
            <!-- <el-icon><DocumentCopy /></el-icon> -->
          </el-button>
        </div>

        <div class="meta-row">
          <span>汇率：1 {{ state.from }} ≈ {{ rateText }} {{ state.to }}</span>
          <div class="meta-right">
            <span class="muted">日期：{{ rates?.date || "--" }}</span>
            <el-button size="small" @click="refresh()">刷新</el-button>
          </div>
        </div>
      </el-form>
    </GlassCard>
  </div>
</template>

<script setup lang="ts">
import { DocumentCopy, Switch } from "@element-plus/icons-vue"
import {
  ElButton,
  ElForm,
  ElFormItem,
  ElIcon,
  ElInputNumber,
  ElMessage,
  ElOption,
  ElSelect,
  ElTag
} from "element-plus"
import { computed, onMounted, reactive } from "vue"

import { getRates, refreshRatesIfStale } from "../scripts/services/rates.js"
// @ts-ignore - SFC default export by Vue plugin
import GlassCard from "./ui/GlassCard.vue"

type RatesPayload = {
  base: string
  date: string
  rates: Record<string, number>
}

const state = reactive({
  amount: 100,
  from: "USD",
  to: "CNY"
})

const rates = reactive<Partial<RatesPayload>>({})

const currencies = computed<string[]>(() => {
  const list = new Set<string>()
  if (rates.base) list.add(rates.base as string)
  const m = rates.rates || {}
  Object.keys(m).forEach((k) => list.add(k))
  return Array.from(list).sort()
})
// 货币英文名与中文名（精简映射，可继续补充）
const zhNames: Record<string, string> = {
  USD: "美元",
  EUR: "欧元",
  GBP: "英镑",
  CNY: "人民币",
  JPY: "日元",
  AUD: "澳元",
  NZD: "纽元",
  CAD: "加元",
  CHF: "瑞郎",
  HKD: "港元",
  SGD: "新加坡元",
  THB: "泰铢",
  TRY: "土耳其里拉",
  SEK: "瑞典克朗",
  NOK: "挪威克朗",
  DKK: "丹麦克朗",
  CZK: "捷克克朗",
  PLN: "波兰兹罗提",
  HUF: "匈牙利福林",
  ISK: "冰岛克朗",
  RON: "罗马尼亚列伊",
  BRL: "巴西雷亚尔",
  MXN: "墨西哥比索",
  ZAR: "南非兰特",
  PHP: "菲律宾比索",
  BGN: "保加利亚列弗",
  KRW: "韩元",
  TWD: "新台币"
}
function displayLabel(code: string): string {
  const zh = zhNames[code]
  return zh ? `${code} ${zh}` : code
}

// ISO 4217 货币代码 -> 国旗 emoji（基于 ISO 3166-1 alpha-2 国家码推导）
function currencyToCountry(code: string): string | null {
  // 覆盖 frankfurter.app 常见货币 → 国家/地区码
  const map: Record<string, string> = {
    // 基本
    USD: "US",
    EUR: "EU", // 欧盟
    GBP: "GB",
    CNY: "CN",
    JPY: "JP",
    // 大洋洲/北美/亚洲
    AUD: "AU",
    NZD: "NZ",
    CAD: "CA",
    HKD: "HK",
    TWD: "TW",
    KRW: "KR",
    SGD: "SG",
    THB: "TH",
    INR: "IN",
    IDR: "ID",
    ILS: "IL",
    MYR: "MY",
    // 欧洲
    CHF: "CH",
    SEK: "SE",
    NOK: "NO",
    DKK: "DK",
    CZK: "CZ",
    PLN: "PL",
    HUF: "HU",
    ISK: "IS",
    RON: "RO",
    TRY: "TR",
    RUB: "RU",
    // 美洲/非洲
    BRL: "BR",
    MXN: "MX",
    ZAR: "ZA",
    PHP: "PH",
    BGN: "BG"
  }
  return map[code] || null
}
function toFlagEmoji(countryCode: string): string {
  // 转为区域指示符号 (Regional Indicator Symbols)
  return countryCode
    .toUpperCase()
    .replace(/./g, (c) => String.fromCodePoint(127397 + c.charCodeAt(0)))
}
function flagEmoji(currencyCode: string): string {
  const cc = currencyToCountry(currencyCode)
  if (!cc) return "" // 未知则不显示
  if (cc === "EU") return "🇪🇺" // 欧盟旗
  return toFlagEmoji(cc)
}

const fxRate = computed<number>(() => {
  const base = rates.base
  const m = rates.rates || {}
  const from = state.from
  const to = state.to
  if (!from || !to || from === to) return 1
  if (!base) return 0
  if (from === base) return m[to] || 0
  if (to === base) return m[from] ? 1 / (m[from] as number) : 0
  const toRate = m[to]
  const fromRate = m[from]
  if (!toRate || !fromRate) return 0
  return (toRate as number) / (fromRate as number)
})

const converted = computed<number>(
  () => (state.amount || 0) * (fxRate.value || 0)
)
const convertedText = computed<string>(() =>
  Number.isFinite(converted.value) ? converted.value.toFixed(2) : "--"
)
const rateText = computed<string>(() =>
  Number.isFinite(fxRate.value) ? fxRate.value.toFixed(6) : "--"
)

function swap() {
  const tmp = state.from
  state.from = state.to
  state.to = tmp
}

async function load() {
  const data = await getRates()
  rates.base = data.base
  rates.date = data.date
  rates.rates = data.rates as any
  // 若默认币种不存在，回退到 base
  if (!currencies.value.includes(state.from)) state.from = data.base
  if (!currencies.value.includes(state.to)) state.to = data.base
}

async function refresh() {
  await refreshRatesIfStale(true)
  await load()
  ElMessage.success("汇率已刷新")
}

async function copyToClipboard(value: number | string) {
  try {
    await navigator.clipboard.writeText(String(value))
    ElMessage.success("已复制")
  } catch (e) {
    ElMessage.error("复制失败")
  }
}

onMounted(() => {
  load()
})
</script>

<style scoped>
.top-row {
  display: grid;
  grid-template-columns: 65px 1fr 65px;
  gap: 8px;
  align-items: center;
}
.code-tag {
  justify-self: start;
}
.swap-icon {
  width: 65px;
  cursor: pointer;
  color: #4b5b76;
  transition: color 0.15s ease;
  justify-self: end;
}
.swap-icon:hover {
  color: #1489fe;
}
.fx-compact :deep(.el-form-item) {
  margin-bottom: 10px;
}
.row-input {
  display: flex;
  align-items: center;
  gap: 8px;
}
.row-input :deep(.el-input-number) {
  flex: none;
}
.row-input .el-button {
  flex: none;
}
.result-text {
  font-weight: 700;
  min-width: 90px;
}
.meta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 10px;
  align-items: center;
  justify-content: space-between;
  font-size: 12px;
  color: #4b5b76;
}
.meta-right {
  display: flex;
  align-items: center;
  gap: 12px;
}
.meta-row .muted {
  opacity: 0.8;
}
.center-actions {
  display: flex;
  align-items: center;
  justify-content: center;
  padding-bottom: 6px;
}
.fx-result {
  margin-top: 6px;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 18px;
}
.fx-result .num {
  font-weight: 800;
}
.fx-result .code {
  font-weight: 700;
}
</style>
